package com.chujian.framework.starter.webmvc;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.chujian.framework.auth.AccessorHolder;
import com.chujian.framework.constant.PlatConst;
import com.chujian.framework.core.tsdata.Result;
import com.chujian.framework.core.tsdata.ResultCode;
import com.chujian.framework.exception.AuthException;
import com.chujian.framework.exception.BaseException;
import com.chujian.framework.exception.BusiExceptioin;
import com.chujian.framework.exception.MsgException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author ：chujian
 * @date ：2020-08-15
 * 全局通用异常处理
 */
@ResponseBody
@ControllerAdvice
@Slf4j
public class BaseExceptionAdvice {

    /**
     * 参数校验失败异常处理 MethodArgumentNotValidException
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Result<?> adviceMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException", e);

        String msg = "参数校验异常：";
        FieldError fieldError = e.getBindingResult().getFieldError();
        if (fieldError != null) {
            msg += fieldError.getDefaultMessage();
        }
        return new Result<>(ResultCode.ERR.getCode(), msg, null);
    }

    /**
     * 提示异常，一般由客户端错误引起
     */
    @ExceptionHandler({MsgException.class})
    public Result<?> adviceMsgException(MsgException e) {
        log.error("MsgException", e);

        return new Result<>(e.getCode(), e.getMessage(), null);
    }

    /**
     * 授权异常，统一返回
     */
    @ExceptionHandler({AuthException.class})
    public Result<?> adviceMsgException(AuthException e) {
        log.error("AuthException", e);
        return new Result<>(e.getCode(), e.getMessage(), null);
    }

    /**
     * BaseException
     */
    @ExceptionHandler({BaseException.class})
    public Result<?> adviceMsgException(BaseException e) {
        log.error("BaseException", e);
        return new Result<>(e.getCode(), e.getMessage(), null);
    }

    /**
     * 业务异常
     */
    @ExceptionHandler({BusiExceptioin.class})
    public Result<?> adviceMsgException(BusiExceptioin e) {
        log.error("BusiExceptioin", e);
        return new Result<>(e.getCode(), e.getMessage(), null);
    }

    /**
     * 500 缺省的未知异常处理
     */
    @ExceptionHandler({Exception.class})
    public Result<?> adviceDftException(Exception e) {
        log.error("Exception", e);

        String msg = "服务开小差了~";
        // PC端，提示消息的错误消息
        if (null != AccessorHolder.getAccessor()
                && PlatConst.PLAT_PC.equals(AccessorHolder.getAccessor().getPlatId())) {
            msg = ExceptionUtil.stacktraceToString(e, 2000);
        }
        return new Result<>(ResultCode.ERR.getCode(), msg, null);
    }

}
